#include "Character.h"

using namespace std;


/**
 * Set the value of m_iGold
 * @param int val - number of gold pieces
 * @return void
 */
void Character::setGold(int val)
{
	m_iGold = val;
}


/**
 * if the item strEquipment exists in itemList:
 *     create an Item in the list m_equipment
 * else
 *     nothing happens.
 * @param const char* strEquipment - the name of the equipment to add
 * @param vector<Item*> itemList - the reference list of items
 * @return itemID or 0 if no item found in the reference list
 */
int Character::addEquipment(const char* strEquipment, vector<Item*> itemList)
{
	for (unsigned int i = 0; i < itemList.size(); ++i)
	{
		if (!(itemList[i]->getName().compare(strEquipment)))
		{
			Item* newItem = new Item;
			*(newItem) = *(itemList[i]);
			m_equipment.push_back(newItem);
			return newItem->getId();
		}
	}
	return 0;
}


/**
 * Removes Item with itemId from the m_equipment list and delete the instance
 * @param int itemId - ID of the item to remove
 * @return void
 */
void Character::delEquipment(int itemId)
{
	for (unsigned int i = 0; i < m_equipment.size(); ++i)
	{
		if (m_equipment[i]->getId() == itemId)
		{
			Item* itemToDelete = m_equipment[i];
			delete itemToDelete;
			m_equipment.erase(m_equipment.begin() + i);
			break;
		}
	}
}


/**
 * if the item with itemID is not already in the backpack
 * add it into the m_backpack list 
 * @param int itemId - ID of the item to add to backpack
 * @return void
 */
void Character::addInBackpack(int itemId)
{
	for (unsigned int i = 0; i < m_backpack.size(); ++i)
	{
		if (m_backpack[i]->getId() == itemId)
		{
			return;
		}
	}
	for (unsigned int i = 0; i < m_equipment.size(); ++i)
	{
		if (m_equipment[i]->getId() == itemId)
		{
			m_backpack.push_back(m_equipment[i]);
			break;
		}
	}
}


/**
 * Removes item with itemID from backpack
 * @param int itemId - ID of the item to remove from backpack
 * @return void
 */
void Character::removeFromBackpack(int itemId)
{
	for (unsigned int i = 0; i < m_backpack.size(); ++i)
	{
		if (m_backpack[i]->getId() == itemId)
		{
			m_backpack.erase(m_backpack.begin() + i);
			break;
		}
	}
}


/**
 * Equips item with itemID to the right hand if item is a weapon only
 * for 2 handed weapon the left hand is also equiped
 * all previously equiped item is placed back into the backpack
 * @see removeFromBackpack()
 * @see unequipRightHand()
 * @see unequipLeftHand()
 * @param int itemId - ID of the item to equip in the right hand
 * @return void
 */
void Character::equipRightHand(int itemId)
{
	for (unsigned int i = 0; i < m_equipment.size(); ++i)
	{
		if ((m_equipment[i]->getId() == itemId) &&
			((m_equipment[i]->getType() == ITEM_TYPE_ONEHANDEDWEAPON) ||
			 (m_equipment[i]->getType() == ITEM_TYPE_TWOHANDEDWEAPON)))
		{
			removeFromBackpack(itemId);
			unequipRightHand();
			m_rightHand = m_equipment[i];
			if (m_equipment[i]->getType() == ITEM_TYPE_TWOHANDEDWEAPON)
			{
				unequipLeftHand();
				m_leftHand = m_equipment[i];
			}
			break;
		}
	}
}


/**
 * Equips item with itemID to the left hand if item is a weapon only
 * for 2 handed weapon the right hand is also equiped
 * all previously equiped item is placed back into the backpack
 * @see removeFromBackpack()
 * @see unequipRightHand()
 * @see unequipLeftHand()
 * @param int itemId - ID of the item to equip in the left hand
 * @return void
 */
void Character::equipLeftHand(int itemId)
{
	for (unsigned int i = 0; i < m_equipment.size(); ++i)
	{
		if ((m_equipment[i]->getId() == itemId) &&
			((m_equipment[i]->getType() == ITEM_TYPE_ONEHANDEDWEAPON) ||
			 (m_equipment[i]->getType() == ITEM_TYPE_TWOHANDEDWEAPON)))
		{
			removeFromBackpack(itemId);
			unequipLeftHand();
			m_leftHand = m_equipment[i];
			if (m_equipment[i]->getType() == ITEM_TYPE_TWOHANDEDWEAPON)
			{
				unequipRightHand();
				m_rightHand = m_equipment[i];
			}
			break;
		}
	}
}


/**
 * Wear item with itemID
 * previously equiped armor is placed into the backpack
 * @see unequipBody()
 * @see removeFromBackpack()
 * @param int itemId - ID of the item to equip in the right hand
 * @return void
 */
void Character::equipBody(int itemId)
{
	for (unsigned int i = 0; i < m_equipment.size(); ++i)
	{
		if ((m_equipment[i]->getId() == itemId) &&
			(m_equipment[i]->getType() == ITEM_TYPE_ARMOR))
		{
			unequipBody();
			removeFromBackpack(itemId);
			m_body = m_equipment[i];
			break;
		}
	}
}


/**
 * Put armor back to the backpack
 * addInBackpack()
 * @param void
 * @return void
 */
void Character::unequipBody()
{
	if (m_body != 0)
	{
		addInBackpack(m_body->getId());
		m_body = 0;
	}
}


/**
 * Remove item from right hand to the backpack
 * if item is 2 handed weapon then left hand is emptied too
 * addInBackpack()
 * @param void
 * @return void
 */
void Character::unequipRightHand()
{
	if (m_rightHand != 0)
	{
		addInBackpack(m_rightHand->getId());
		if (m_rightHand->getType() == ITEM_TYPE_TWOHANDEDWEAPON)
			m_leftHand = 0;
		m_rightHand = 0;
	}
}


/**
 * Remove item from left hand to the backpack
 * if item is 2 handed weapon then right hand is emptied too
 * addInBackpack()
 * @param void
 * @return void
 */
void Character::unequipLeftHand()
{
	if (m_leftHand != 0)
	{
		addInBackpack(m_leftHand->getId());
		if (m_leftHand->getType() == ITEM_TYPE_TWOHANDEDWEAPON)
			m_rightHand = 0;
		m_leftHand = 0;
	}
}


/**
 * Get Item equiped in right hand
 * @param void
 * @return Item* - Item in right hand
 */
Item* Character::getRightHandItem()
{
	return m_rightHand;
}


/**
 * Get Item equiped in left hand
 * @param void
 * @return Item* - Item in left hand
 */
Item* Character::getLeftHandItem()
{
	return m_leftHand;
}


/**
 * Get armor equiped
 * @param void
 * @return Item* - Armor worn
 */
Item* Character::getBodyItem()
{
	return m_body;
}


/**
 * Adds gold for the Character
 * @param int val - amount of gold to add
 * @return void
 */
void Character::addGold(int val)
{
	m_iGold += val;
}


/**
 * Returns amount of Gold 
 * @param void
 * @return int = number of gold pieces
 */
int Character::getGold()
{
	return m_iGold;
}


/**
 * Returns number of items in equipment.
 * @param void
 * @return int = number of items
 */
int Character::getNumItemInEquipment()
{
	return m_equipment.size();
}